package educrypt.ciphers.hill;

import java.util.HashMap;
import java.util.Map;

import educrypt.commons.Alphabet;

public class HillNgram {

	private Alphabet alphabet;
	private StringBuffer rawNgram; // Ngram with known and unknown symbols
	private StringBuffer realNgram; // Ngram with known symbols in lowercase
	private Map<Integer, Integer> correspondences; // Correspondence between
													// known symbols
													// position in both
													// ngrams

	public HillNgram(Alphabet alphabet) {
		this.rawNgram = new StringBuffer();
		this.realNgram = new StringBuffer();
		this.correspondences = new HashMap<Integer, Integer>();
		this.alphabet = alphabet;
	}

	public void addSymbol(char symbol) {
		if (this.alphabet.containsSymbol(symbol)) {
			addKnownSymbol(symbol);
		} else {
			addUnknownSymbol(symbol);
		}
	}

	private void addKnownSymbol(char symbol) {
		rawNgram.append(symbol);
		realNgram.append(Character.toLowerCase(symbol));
		correspondences.put(realNgram.length() - 1, rawNgram.length() - 1);
	}

	private void addUnknownSymbol(char symbol) {
		rawNgram.append(symbol);
	}

	public String getTransformedRawNgram(String encodedRealNgram) {
		StringBuffer encodedRawNgram = new StringBuffer(this.rawNgram);
		for (int realPos = 0; realPos < encodedRealNgram.length(); realPos++) {
			char encodedSymbol = encodedRealNgram.charAt(realPos);
			int rawPos = this.correspondences.get(realPos);
			if (Character.isUpperCase(encodedRawNgram.charAt(rawPos))) {
				encodedSymbol = Character.toUpperCase(encodedSymbol);
			}
			encodedRawNgram.setCharAt(rawPos, encodedSymbol);
		}
		return encodedRawNgram.toString();
	}

	public String getRealNgram() {
		return realNgram.toString();
	}

	public String getRawNgram() {
		return realNgram.toString();
	}

	public int size() {
		return realNgram.length();
	}

	public String toString() {
		return realNgram.toString();
	}
}